﻿using IPluginInterface;
using Qting.AOI.Serialize;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using YiNing.Tools;

namespace LixunYueNan
{
    [Serializable]
    public class MesPlugin : MarshalByRefObject, IAoiPlugin
    {
        /// <summary>
        /// 哪条线是T面， 1：1轨道T面， 2：2轨道T面， 3：两条轨道都是T面 4：两条轨道都不是T面
        /// </summary>
        private int unbindLine = -1;
        private LixunArgs lixunArgsLine1, lixunArgsLine2;
        private ErrorCodes errorCodes;
        /// <summary>
        /// 是否启用插件
        /// </summary>
        private bool enablePlugin = true;
        public string Tag
        {
            get;
            private set;
        }

        public Version Version
        {
            get;
            private set;
        }

        public string Description
        {
            get;
            private set;
        }


        public MesPlugin()
        {
            Tag = "临时版本！！！！立讯Mes插件(德中立讯BU17-越南)";
            Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            Description = "德中立讯BU17-越南--正式版";
        }
        public PluginResult Init(params object[] args)
        {
            enablePlugin = args.Length == 0 ? true : (bool)args[0];
            errorCodes = ErrorCodes.LoadThis();
            lixunArgsLine1 = LixunArgs.LoadThis(1);
            lixunArgsLine2 = LixunArgs.LoadThis(2);
            if (lixunArgsLine1.UnbindEnable) unbindLine = 1;
            if (lixunArgsLine2.UnbindEnable) unbindLine = 2;
            if (lixunArgsLine1.UnbindEnable && lixunArgsLine2.UnbindEnable) unbindLine = 3;
            if (!lixunArgsLine1.UnbindEnable && !lixunArgsLine2.UnbindEnable) unbindLine = 4;
            if (!File.Exists(ErrorCodes.GetThisFileName()))
            {
                errorCodes.ErrorCodeCustomer = new List<ErrorCode>();
                var values = Enum.GetValues(typeof(ResultTypeCn));
                for (int i = 0; i < values.Length; i++)
                {
                    var oneEnum = values.GetValue(i).ToString();
                    ErrorCode errorCode = new ErrorCode();
                    errorCode.ErrorCodeIndex = i;
                    errorCode.ErrorCodeAOI = oneEnum;
                    errorCode.ErrorCodeMES = ((ResultTypeCn)i).ToString();
                    errorCodes.ErrorCodeCustomer.Add(errorCode);
                }
            }
     

            return new PluginResult();
        }

        public PluginResult Start(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            //aoiPcbs.pcb_name = "Start";
            return new PluginResult();
        }

        public PluginResult BeforeProductIn(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            //aoiPcbs.pcb_name = "BeforeProductIn";
            return new PluginResult();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="aoiPcbs"></param>
        /// <param name="bDual"> false 表示 1轨道     true 表示 2轨道</param>
        /// <param name="args"></param>
        /// <returns></returns>
        public PluginResult ProductIn(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            PluginResult pluginResult = new PluginResult();
            //pluginResult = CheckRoute(aoiPcbs, bDual);

            return pluginResult;
        }

        public PluginResult AfterProductIn(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            //aoiPcbs.pcb_name = "AfterProductIn";
            return new PluginResult();
        }
        public PluginResult BeforeProductOut(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            PluginResult pluginResult = new PluginResult();
            pluginResult = CheckRoute(aoiPcbs, bDual);

            return pluginResult;
        }

        public PluginResult ProductOut(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            PluginResult pluginResult = new PluginResult();
            return pluginResult;
        }

        public PluginResult AfterProductOut(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            return new PluginResult();
        }

        public PluginResult Done(ref AoiPcbs aoiPcbs, bool bDual = false, params object[] args)
        {
            PluginResult pluginResult = new PluginResult();

            pluginResult = ThroughRoute(aoiPcbs, bDual);
            if (pluginResult.Status == Status.Continue)
            {
                #region 解绑操作
                pluginResult = Unbind(aoiPcbs, bDual);
                #endregion
            }

            return pluginResult;
        }

 
        public void OpenSettingForm(params object[] args)
        {
            new Settings(lixunArgsLine1, lixunArgsLine2, errorCodes, this, unbindLine).ShowDialog();
        }
        
        public PluginResult YiNing(ref AoiPcbs spiPcbs, params object[] args)
        {
            throw new NotImplementedException();
        }

        public void Dispose()
        { 
        }


        private PluginResult CheckRoute(AoiPcbs aoiPcbs, bool bDual)
        {
            LixunArgs lixunArgs = bDual ? lixunArgsLine2 : lixunArgsLine1;
            //LogHelper.WriteLog(JsonHelper.Serialize(aoiPcbs));
            PluginResult pluginResult = new PluginResult();
            if (!enablePlugin) return pluginResult;
            // 先判断 T还是B面
            if (((unbindLine == 1 && !bDual) || (unbindLine == 2 && bDual)) || unbindLine == 3) // T面
            {
                string sn = aoiPcbs.m_barcodeList.Count > 0 ? aoiPcbs.m_barcodeList.Find(v => v.FunctionType == 1)?.strBarcode : "";
                if (sn == null)
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = "条码为空";
                    return pluginResult;
                }
                LogHelper.WriteLog("Start T CheckRoute");
                string postData = string.Format(
                    "sn={0}&c={1}&p={2}&treel_no&tsid={3}",
                    sn,
                    lixunArgs.CheckRouteC,
                    lixunArgs.CheckRouteP,
                    lixunArgs.BaseTsid);
                string res = HttpPost(lixunArgs.BaseMesUrl, postData);
                if((res.Contains("0 SFC_OK") && !res.Contains(" OK") && !res.Contains(" NG")) && (res.Contains("0 SFC_OK") && !res.Contains("\nOK") && !res.Contains("\nNG")))
                {
                    // 这边解绑治具，并报警
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = "AOI 解绑 - mes返回：" + res;
                    Unbind(aoiPcbs, bDual);
                }
                else if ((!res.Contains("0 SFC_OK OK")) && !res.Contains("0 SFC_OK \nOK") && !res.Contains("0 SFC_OK \r\nOK") && !res.Contains("0 SFC_OK\nOK") && !res.Contains("0 SFC_OK\r\nOK"))
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = res;
                }
                LogHelper.WriteLog("End T CheckRoute");
            }
            else // B面
            {
                foreach(var one in aoiPcbs.m_barcodeList)
                {
                    if (one.FunctionType != 0) continue;
                    LogHelper.WriteLog("Start B 子板：" + one.subBoard + " CheckRoute");
                    string sn = one.strBarcode;
                    //if ((sn == null || sn.Equals("")) && aoiPcbs.m_badBoardList.Find(v => v.Board == one.subBoard && v.IsBad == false) != null)
                    //{
                    //    pluginResult.Status = Status.Alarm;
                    //    pluginResult.ErrorMsg = "条码为空";
                    //    return pluginResult;
                    //}

                    if (sn == null || sn.Equals(""))
                    {
                        continue;
                    }
                    string postData = string.Format(
                                       "p={0}&c={1}&sw_version={2}&tsid={3}&sn={4}&fixture_id={5}&head_id={6}",
                                       lixunArgs.CheckRouteP,
                                       lixunArgs.CheckRouteC,
                                       lixunArgs.BaseSwVersion,
                                       lixunArgs.BaseTsid,
                                       sn,
                                       lixunArgs.BaseFixtureId, "");
                    string res = HttpPost(lixunArgs.BaseMesUrl, postData);
                    if ((!res.Contains("unit_process_check=") && !res.Contains(",OK")) || (res.Contains("unit_process_check=") && !res.Contains(",OK")))
                    {
                        pluginResult.Status = Status.Alarm;
                        pluginResult.ErrorMsg = res;
                        break;
                    }
                    LogHelper.WriteLog("End B 子板：" + one.subBoard + " CheckRoute");
                }
               
            }
            return pluginResult;
        }

        private PluginResult ThroughRoute(AoiPcbs aoiPcbs, bool bDual)
        {
            LixunArgs lixunArgs = bDual ? lixunArgsLine2 : lixunArgsLine1;
            PluginResult pluginResult = new PluginResult();
            if (!enablePlugin) return pluginResult;
            // 先判断 T还是B面
            if (((unbindLine == 1 && !bDual) || (unbindLine == 2 && bDual)) || unbindLine == 3) // T面
            {
                string sn = aoiPcbs.m_barcodeList.Count > 0 ? aoiPcbs.m_barcodeList.Find(v => v.FunctionType == 1)?.strBarcode : "";
                if (sn == null)
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = "条码为空";
                    return pluginResult;
                }
                LogHelper.WriteLog("Start T Through");
                string postData = string.Format(
                    "sn=sn&c={1}&p={2}&product={3}&fixture_id={4}" +
                    "&test_station_name={5}&station_id={6}&sw_version={7}" +
                    "&start_time={8}&stop_time={9}" +
                    "&treel_no={11}&tsid={10}&op={12}",
                    sn, lixunArgs.ThroughRouteC, lixunArgs.ThroughRouteP, lixunArgs.ThroughRouteProduct, sn, 
                    lixunArgs.BaseTestStationName, lixunArgs.BaseTsid, lixunArgs.BaseSwVersion,
                    aoiPcbs.create_time.ToString("yyyy-MM-dd HH:mm:ss"), aoiPcbs.end_time.ToString("yyyy-MM-dd HH:mm:ss"), lixunArgs.BaseTsid,
                    GetPartStatus(aoiPcbs), lixunArgs.BaseOP);
                string res = HttpPost(lixunArgs.BaseMesUrl, postData);
                if (!res.Contains("0 SFC_OK"))
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = res;
                }
                LogHelper.WriteLog("End T Through");
            }
            else // B面
            {
                string sn = aoiPcbs.m_barcodeList.Count > 0 ? aoiPcbs.m_barcodeList.FindLast(v => v.FunctionType == 0)?.strBarcode : "";
                if (sn == null)
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = "条码为空";
                    return pluginResult;
                }
                LogHelper.WriteLog("Start B Through");
                string postData = string.Format(
                                   "sn=sn&c={1}&p={2}&product={3}&test_station_name={4}" +
                                   "&station_id={5}&sw_version={6}&start_time={7}&stop_time={8}" +
                                   "&fixture_id={9}&tsid={10}" +
                                   "&treel_no={11}&op={12}",
                                    sn, lixunArgs.ThroughRouteC, lixunArgs.ThroughRouteP, lixunArgs.ThroughRouteProduct, lixunArgs.BaseTestStationName,
                                    lixunArgs.BaseTsid, lixunArgs.BaseSwVersion, aoiPcbs.create_time.ToString("yyyy-MM-dd HH:mm:ss"), aoiPcbs.end_time.ToString("yyyy-MM-dd HH:mm:ss"),
                                    lixunArgs.BaseFixtureId, lixunArgs.BaseTsid,
                                    GetPartStatus(aoiPcbs), lixunArgs.BaseOP
                                   );
                string res = HttpPost(lixunArgs.BaseMesUrl, postData);
                if ((!res.Contains("unit_process_check=") && !res.Contains(",OK")) || (res.Contains("unit_process_check=") && !res.Contains(",OK")))
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = res;
                }
                LogHelper.WriteLog("End B Through");
            }
            return pluginResult;
        }
        private PluginResult Unbind(AoiPcbs aoiPcbs, bool bDual)
        {
            PluginResult pluginResult = new PluginResult();
            if (!enablePlugin) return pluginResult;
            // 先判断 T还是B面
            if (((unbindLine == 1 && !bDual) || (unbindLine == 2 && bDual)) || unbindLine == 3) // T面
            {
                string sn = aoiPcbs.m_barcodeList.Count > 0 ? aoiPcbs.m_barcodeList.Find(v => v.FunctionType == 1)?.strBarcode : "";
                if (sn == null)
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = "条码为空";
                    return pluginResult;
                }
                LogHelper.WriteLog("Start Unbind");
                string postData = string.Format(
                    "sn={0}&c={1}&p={2}&tsid={3}",
                    sn, lixunArgsLine1.UnbindC, lixunArgsLine1.UnbindP, lixunArgsLine1.BaseTsid);
                string res = HttpPost(lixunArgsLine1.BaseMesUrl, postData);
                if (!res.Contains("0 SFC_OK OK"))
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = res;
                }
                LogHelper.WriteLog("End Unbind");
            }
            else // B面
            {
                string sn = aoiPcbs.m_barcodeList.Count > 0 ? aoiPcbs.m_barcodeList.FindLast(v => v.FunctionType == 0)?.strBarcode : "";
                if (sn == null)
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = "条码为空";
                    return pluginResult;
                }
                LogHelper.WriteLog("Start Unbind");
                string postData = string.Format(
                    "sn={0}&c={1}&p={2}&tsid={3}",
                    sn, lixunArgsLine2.UnbindC, lixunArgsLine2.UnbindP, lixunArgsLine2.BaseTsid);
                string res = HttpPost(lixunArgsLine2.BaseMesUrl, postData);
                if ((!res.Contains("0 SFC_OK OK")) ||(!res.Contains("unit_process_check=") && !res.Contains(",OK")) || (res.Contains("unit_process_check=") && !res.Contains(",OK")))
                {
                    pluginResult.Status = Status.Alarm;
                    pluginResult.ErrorMsg = res;
                }
                LogHelper.WriteLog("End Unbind");
            }
            return pluginResult;
        }

        private string GetPartStatus(AoiPcbs aoiPcbs)
        {
            string allBoardStr = "";
            for(int i =0; i< aoiPcbs.pcb_childen_number; i++)
            {
                string oneBoardRes = "";
                try
                {
                    tagBarcodeInfo barcodeInfo = aoiPcbs.m_barcodeList.Find(u => u.subBoard == i + 1 && u.FunctionType == 0);
                    oneBoardRes += barcodeInfo?.strBarcode + ",";
                }
                catch (Exception er)
                {
                }
                oneBoardRes += "D"+(i + 1).ToString().PadLeft(3, '0');
                string partStatus = "";
                foreach (var one in aoiPcbs.results_2d)
                {
                
                    if (one.SubBoard != i + 1 || one.IsMisjudge > 0) continue;
                    try
                    {
                        string strNg = one.ResultString.Split(',')[0].Replace(",", "");
                        if (strNg.IndexOf('(') != -1) strNg = strNg.Substring(0, strNg.IndexOf('('));
                        var find = errorCodes.ErrorCodeCustomer.Find(v => v.ErrorCodeIndex == (int)Enum.Parse(typeof(ResultTypeCn), strNg));
                        string erCode = find == null ? strNg : find.ErrorCodeMES;
                        //partStatus += string.Format("{0}:{1}#", erCode, one.PartName);
                        partStatus += string.Format("{0}#", erCode);
                        break;
                    }
                    catch (Exception er)
                    {

                    }
                }
                if (partStatus.EndsWith("#")) partStatus = partStatus.Remove(partStatus.Length - 1);
                oneBoardRes += partStatus.Length == 0 ? ",PASS" : ",FAIL|" + partStatus;
                allBoardStr += oneBoardRes + ";";
            }
            if (allBoardStr.EndsWith(";")) allBoardStr = allBoardStr.Remove(allBoardStr.Length - 1);
            return allBoardStr;
        }

        CookieContainer cookie = new CookieContainer();
        private string HttpPost(string Url, string postDataStr)
        {
            LogHelper.WriteLog("请求参数:" + postDataStr);
            string retString = "";
            //retString = "0 SFC_OK tsid::ITKS_RFVN-CB01-AOI-201::unit_process_check=DLC3104B0F12392DH,DLC3104B0F12392DH 需使用:复测模式/当前:正常模式;";
            //return retString;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                //request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
                request.CookieContainer = cookie;
                Stream myRequestStream = request.GetRequestStream();
                StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
                myStreamWriter.Write(postDataStr);
                myStreamWriter.Close();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                response.Cookies = cookie.GetCookies(response.ResponseUri);
                Stream myResponseStream = response.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                retString = myStreamReader.ReadToEnd();
                myStreamReader.Close();
                myResponseStream.Close();
                LogHelper.WriteLog("返回结果:" + retString);
            }
            catch(Exception er)
            {
                retString = er.Message;
                LogHelper.WriteLog("异常结果:" + er.Message);
            }

            return retString;
        }
    }
}
